import { yunNao } from "./yunNao"
import { yunNaoAccount } from "@src/dataFormatConversion/constant"
import { SystemEnum } from "@src/dataFormatConversion/enum"
import { encrypt, getDataFromLocalStorage, promisetTimeOut } from "@src/utils/common"
import { saveDataToLocalStorage } from "@src/utils/common"

type Request = {
  (input: RequestInfo | URL, data:any, init?: RequestInit | undefined, originRes?:Boolean): Promise<any>
}
const getUserAgent = () => {
  return navigator.userAgent
}
type RequestSD = {
  (input: RequestInfo | URL, data:any, init?: RequestInit | undefined, responseType?:any): Promise<any>
}

const getAreaCode = () => {
  return '370000'
}
const getAppId = (url:any) => {
  if(typeof url !== 'string') return ''
  if(url.includes('forward/brain')) return '3101'
  if(url.includes('forward/netrm')) return '5000'
  return ''
}

export const requestSDspotMarket:RequestSD = async (input, data, init, responseType = 'json') => {
  try {
    const reqConfig:RequestInit = {
      method: "post",
      body: data,
      referrer: "about:client",
      // referrerPolicy: "no-referrer-when-downgrade",
      referrerPolicy: "strict-origin-when-cross-origin",
      mode: "cors", 
      credentials: "include",
      cache: "default",
      redirect: "follow",
      integrity: "",
      keepalive: true,
      signal: undefined,
      ...init,
      headers: {
        'Area-Code': getAreaCode(),
        Appid: getAppId(input),
        Accept: 'application/json, text/javascript, */*; q=0.01',
        'User-Agent': getUserAgent(),
        // 'X-Requested-With':'XMLHttpRequest',
        ...(init?.headers || {})
      },
    }

    if(reqConfig.method === 'get') delete reqConfig.body

    const response = await fetch(input, {...reqConfig})

    if (!(response.status >= 200 && response.status < 300)) return Promise.reject(new Error(response.statusText))
    let resData;
    if(responseType === 'json') (resData = await response?.json())
    if(responseType === 'blob') (resData = await response?.blob())
    if(responseType === 'text') (resData = await response?.text())
    return Promise.resolve(resData)
  } catch(e) {
    console.error(e)
    return Promise.reject(e)
  }
}

export const requestSDspotMarketZcq:RequestSD = async (input, data, init, responseType = 'json') => {
  try {
    const reqConfig:RequestInit = {
      method: "post",
      body: data,
      referrer: "about:client",
      // referrerPolicy: "no-referrer-when-downgrade",
      referrerPolicy: "strict-origin-when-cross-origin",
      mode: "cors", 
      credentials: "include",
      cache: "default",
      redirect: "follow",
      integrity: "",
      keepalive: true,
      signal: undefined,
      ...init,
      headers: {
        Accept: 'application/json, text/javascript, */*; q=0.01',
        'User-Agent': getUserAgent(),
        'X-Requested-With':'XMLHttpRequest',
        'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
        'Sec-Ch-Ua-Mobile':'?0',
        'Sec-Ch-Ua-Platform':"Windows",
        'Sec-Fetch-Site':'same-origin',
        'Sec-Ch-Ua': `"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"`,
        ...(init?.headers || {})
      },
    }

    if(reqConfig.method === 'get') delete reqConfig.body

    if(data instanceof FormData) {
      delete (reqConfig as any).headers['Content-Type']
    }
    const response = await fetch(input, reqConfig)

    if (!(response.status >= 200 && response.status < 300)) return Promise.reject(new Error(response.statusText))
    let resData;
    if(responseType === 'json') (resData = await response?.json())
    if(responseType === 'blob') (resData = await response?.blob())
    if(responseType === 'text') (resData = await response?.text())
    return Promise.resolve(resData)
  } catch(e) {
    console.error(e)
    return Promise.reject(e)
  }
}

/**云脑的请求fetch */
export const yunNaoRequest:Request = async (input, data, init, originRes = false) => {
  try {
    const reqConfig:RequestInit | Record<any, any> = {
      method: "post",
      body: undefined,
      referrer: "about:client",
      referrerPolicy: "strict-origin-when-cross-origin",
      mode: "cors", 
      credentials: "same-origin",
      cache: "default",
      redirect: "follow",
      integrity: "",
      keepalive: false,
      signal: undefined,
      ...init,
      headers: {
        'Area-Code': getAreaCode(),
        Appid: getAppId(input),
        Accept: 'application/json, text/javascript, */*; q=0.01',
        'User-Agent': getUserAgent(),
        'X-Requested-With':'XMLHttpRequest',
        ...(init?.headers || {})
      },
    }

    let response = await fetch(input, {...reqConfig})

     /**如果状态码为 401 即token过期或者不对则调用云脑登录接口拿到新的token替换 */
     if(response.status === 401 || response.status === 403){
       try {
        const res = await yunNao.login({
          encryptData: encrypt(yunNaoAccount),
          encryptLogin:true
        })
        saveDataToLocalStorage(res.access_token,'access_token')
        await promisetTimeOut(300)
        const newToken = await getDataFromLocalStorage('access_token')
        reqConfig.headers.Authorization = SystemEnum.TOKEN_Bearer + " " + newToken
        response = await fetch(input, {...reqConfig}) // 重新保存一次数据
       } catch (error) {
        console.log('error: ', error);
       }
     }

    if (!(response.status >= 200 && response.status < 300)) return Promise.reject(new Error(response.statusText))
    let resData = {}
    /**解决空响应报错问题 */
    if(init?.credentials=== "omit" || originRes){
      resData = response
    }else{
       resData = await response.json()
    }
    self?.LogDB?.addMulitHistory(input as string, data)
    return Promise.resolve(resData)
  } catch(e) {
    console.error(e)
    self?.LogDB?.addMulitHistory(input as string, data, false)
    return Promise.reject(e)
  }
}

/**
 * Blob 下载文件
 * @param blob  二进制流数据
 * @param fileName  文件名
 */
export function blobToFile (blob:globalThis.Blob | MediaSource, fileName:string) {
  if ('download' in document.createElement('a')) {
    const link = document.createElement('a')
    link.href = window.URL.createObjectURL(blob) // 创建下载的链接
    link.download = fileName // 下载后文件名
    link.style.display = 'none'
    document.body.appendChild(link)
    link.click()
    window.URL.revokeObjectURL(link.href)
    document.body.removeChild(link)
  } else {
    // IE10+下载
    // window.navigator.msSaveBlob(blob, fileName)
  }
}

/**
 * 下载文件
 * @param url 接口地址
 * @param params 接口参数
 * @param method 默认为 post
 * @param fileName  自定义文件名
 */
type DownFile = {
  (input: RequestInfo | URL, init: RequestInit, fileName:string, downloadMainSystem?:boolean): Promise<any>
}
export const downloadFile:DownFile = async (url = '', params:any = {}, fileName = '', downloadMainSystem = false) => {
  const response = await yunNaoRequest(url, undefined, params, true)
  const headers = response.headers
  const data = await response.blob()

  
  if (!fileName && (fileName = headers?.get('content-disposition')?.split('=')[1])) {
    headers.filenamecharset === 'ISO8859-1' && (fileName = escape(fileName))
    fileName = decodeURIComponent(fileName)
  }
  
  if(downloadMainSystem) return Promise.resolve({data, fileName})

  blobToFile(data, fileName || '请自定义或接口返回文件名')
}
